﻿using AutoMapper;
using HomeCloudStorageSystem.Dtos;
using HomeCloudStorageSystem.Models;
using HomeCloudStorageSystem.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.JsonWebTokens;
using Newtonsoft.Json;
using System.Security.Claims;
using HomeCloudStorageSystem.DataBase;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore;
using System.Reflection;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json.Linq;
//using System.Xml.XPath;

namespace HomeCloudStorageSystem.Controllers
{
    /// <summary>
    /// 用户控制器
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class UsersController : ControllerBase
    {
        private readonly IUserRepository _userRepository;
        private readonly IMapper _mapper;
        private readonly AppDbContext _context;
        public UsersController(IUserRepository userRepository,IMapper mapper,AppDbContext appDbContext)
        {
            _userRepository = userRepository;
            _mapper = mapper;
            _context = appDbContext;
        }
        /// <summary>
        /// 请求用户列表
        /// </summary>
        /// <param name="keyword">查询字符串</param>
        /// <returns>用户列表</returns>
        [HttpGet]
        public IActionResult GetUsers([FromQuery] string? keyword)
        {
            var usersFromRepository = _userRepository.GetUsers(keyword);
            if(usersFromRepository == null)
            {
                return NotFound("没有数据的");
            }
            return Ok(usersFromRepository);
        }
        /// <summary>
        /// 根据ID请求用户数据
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns>用户数据</returns>
        [HttpGet("{id}")]
        public IActionResult GetUserById([FromRoute] int id)
        {
            var userFromRepository = _userRepository.GetUserById(id);
            if(userFromRepository == null)
            {
                return NotFound("没有数据");
            }
            return Ok(userFromRepository);
        }
        /// <summary>
        /// 获取用户个人信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("user")]
        public IActionResult GetUser()
        {
            string userName = User.Claims.FirstOrDefault(n => n.Type == ClaimTypes.NameIdentifier)?.Value;
            var userData = _userRepository.GetUserByUserName(userName);

            return Ok(userData);
        }
        /// <summary>
        /// 修改用户信息，禁用用户也是这个接口(修改用户状态 State 为1)
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <param name="patchDocument">修改信息</param>
        /// <returns>修改成功信息</returns>
        [HttpPatch("{id}")]
        public IActionResult UpdateUser([FromRoute] int id, [FromBody] UserForUpdateDto userForUpdateDto)
        {
            if (string.IsNullOrEmpty(id.ToString()) || string.IsNullOrEmpty(userForUpdateDto.FieldName) || userForUpdateDto.FieldValue == "")
            {
                return BadRequest("请求信息错误");
            }
            if (_userRepository.GetUserById(id) == null)
            {
                return BadRequest("请求信息错误");
            }
            var user = _userRepository.GetUserById(id);
            var entry = _context.Entry(user);
            // 使用反射获取字段属性
            PropertyInfo propertyInfo = user.GetType().GetProperty(userForUpdateDto.FieldName);
            if (!propertyInfo.CanWrite)
            {
                return NotFound("未找到该用户");
            }
            if(propertyInfo.Name == "UserName" && _userRepository.GetUserByUserName(userForUpdateDto.FieldValue) !=null)
            {
                return Conflict("用户名已被占用");
            }
            entry.State = EntityState.Modified;
            if (propertyInfo.PropertyType == typeof(string))
            {//动态设置字段的值
                propertyInfo.SetValue(user, userForUpdateDto.FieldValue);
            }
            else
            {// 将 string 类型转换成字段的反射类型
                object value = Convert.ChangeType(JsonConvert.DeserializeObject(userForUpdateDto.FieldValue, propertyInfo.PropertyType), propertyInfo.PropertyType);
                //动态设置字段的值
                propertyInfo.SetValue(user, value);
            }
            // 显示标记属性也被修改
            entry.Property(userForUpdateDto.FieldName).IsModified = true;
            try
            {
                _context.SaveChanges();
            }
            catch
            {
                throw;
            }
            return Ok("修改成功！");
        }
    }
}
